/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package biofilter.filters;

import biofilter.exceptions.InvalidRecordException;
import biofilter.records.Record;
import biofilter.sources.RecordsSourceIF;
import java.util.LinkedList;

/**
 * To provide default implementations of the RecordsFilter patterns in a way that
 * is common to most split filters, according to the pipes and filters pull filter
 * pattern.
 *
 * @author yan,tom,rox,avinash,dan
 */
public abstract class SplitFilterBase extends RecordsFilter {

        // 0
        // 1
        // 2..n

        // This behaviour assumes that we want to store the result from the split
        // The transform record method is responsible for the outputQueue. The
        // challange now is how to make the outputQueue
    protected LinkedList<Record> outputQueue = new LinkedList<Record>();

    /** Creates a new instance of SplitFilterBase */
    public SplitFilterBase() {
        super();
    }

    /** Creates a new instance of SplitFilterBase
     * @param RecordsSource
     */
    public SplitFilterBase( RecordsSourceIF rs ) {
        super(rs);
    }

    /**
     * To get the original record, maintain the original records and transfomred
     * records lists, and to call transformRecord to transform the record
     * @return Record - the transformed record
     */
    public Record getRecord() throws InvalidRecordException {
        this.transformedRecord = null;

                if( this.outputQueue.isEmpty()) {
                        if ( !eof()) {
                                this.originalRecord = source.getRecord();
                                if ( this.originalRecord != null) {
                                        if ( trackOriginalRecords) {
                                                this.originalRecords.add( this.originalRecord);
                                        }

                                        this.transformedRecord = this.transformRecord( this.originalRecord);

                                        if ( trackTransformedRecords) {
                                                this.transformedRecords.add( this.transformedRecord);
                                        }
                                }  // end if this.originalRecord not null
                        } // end if not eof
                }
                else {
            this.transformedRecord = (Record) outputQueue.removeFirst();
            if ( trackTransformedRecords) {
                this.transformedRecords.add( this.transformedRecord);
            }
                }
                return this.transformedRecord;
    }

    /**
     * To indicate whether all records have been processed and returned by this filter.
     * @return boolean - true if all records have been processed, false if not
     */
    public boolean eof() {
        return ( this.source.eof() && this.outputQueue.isEmpty());
    }
}